/* -*-jde-*- */
package app.alumnoe;

import app.conexion.Conexion;
import app.conexion.ConexionException;
import app.empresa.Vacante;
import app.htmlGenerator.HTMLCVGenerator;
import app.htmlGenerator.HTMLVacanteGenerator;
import app.util.Fecha;
import app.util.SQLInjectionException;
import app.util.Validator;
import app.util.appException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Bean Alumno / Egresado Genera un Alumno / Egresado dependiendo del
 * identificador de usuario
 *
 * @author Victor Miguel Peralta Santa Anna
 * @since Diciembre 2011
 * @version 0.1
 */
public class AlumnoE {

    /**
     * El identificador de usuario general
     */
    private int nIdUsuario;
    /**
     * Estudiante / Egresado de la carrera nCarreras
     */
    private int nCarreras;
    /**
     * Ultimo grado academico obtenido
     */
    private int nUltimoGrado;
    /**
     * Si la persona es estudiante o egresado
     */
    private boolean bEstudianteEgresado;
    /**
     * El nombre del la persona
     */
    private String sNombre;
    /**
     * Apellido paterno de la persona
     */
    private String sApellidoPaterno;
    /**
     * Apelñlido materno de la persona
     */
    private String sApellidoMaterno;
    /**
     * Número de cuenta para su identificación
     */
    private String sNumeroCuenta;
    /**
     * Su fecha de nacimiento
     */
    private Fecha dFechaNacimiento;
    /**
     * El identificador de curriculum vitae asignado a la persona.
     */
    private int nIdCV;
    /**
     * La representación en cadena de la carrera que tiene el alumno
     */
    private String scarrera;
    /**
     * La representación en cadena del grado que tiene el alumno
     */
    private String sgrado;
    /**
     * La cadena que contendrá el CV del alumno completo con todo y todo.
     */
    private String htmls;

    /**
     * Constructor para un Alumno.
     *
     * @param nIdUsuario El identificador del usuario
     * @param nCarreras El identificador para la carrera del usuario
     * @param nUltimoGrado El identificador para el ultimo grado del usuario
     * @param bEstudianteEgresado Si sigue siendo estudiante o no
     * @param sNombre El nombre del usuario
     * @param sApellidoPaterno El apellido paterno del usuario
     * @param sApellidoMaterno El apellido materno del usuario
     * @param sNumeroCuenta El numero de cuenta para el usuario
     * @param dFechaNacimiento La fecha de nacimiento del usuario
     * @param nIdCV El identificador del CV del usuario.
     */
    public AlumnoE(int nIdUsuario, int nCarreras, int nUltimoGrado, boolean bEstudianteEgresado,
            String sNombre, String sApellidoPaterno, String sApellidoMaterno, String sNumeroCuenta,
            Fecha dFechaNacimiento, int nIdCV) {
        this.nIdUsuario = nIdUsuario;
        this.nCarreras = nCarreras;
        this.nUltimoGrado = nUltimoGrado;
        this.bEstudianteEgresado = bEstudianteEgresado;
        this.sNombre = sNombre;
        this.sApellidoPaterno = sApellidoPaterno;
        this.sApellidoMaterno = sApellidoMaterno;
        this.sNumeroCuenta = sNumeroCuenta;
        this.dFechaNacimiento = dFechaNacimiento;
        this.nIdCV = nIdCV;
        try {
            setCarreraYGrado();
        } catch (appException ex) {
            System.err.println(ex);
            Logger.getLogger(AlumnoE.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Contruye un alumno con los datos de la base de datos dado el id
     *
     * @param nIdUsuario
     */
    public AlumnoE(int nIdUsuario) throws appException {

        try {

            Conexion con = new Conexion();
            String query = "select * from alumnos where nidusuario = " + nIdUsuario + ";";

            if (!Validator.checkSQLInjection(query)) {
                ResultSet r = con.exec(query);

                while (r.next()) {

                    int id1 = r.getInt("ncarreras");
                    int id2 = r.getInt("nultimogrado");
                    int id3 = r.getInt("nidcv");
                    boolean b1 = r.getBoolean("bestudianteegresado");
                    String s1 = r.getString("snombre");
                    String s2 = r.getString("sapellidopaterno");
                    String s3 = r.getString("sapellidomaterno");
                    String s4 = r.getString("snumerocuenta");
                    Fecha f1 = new Fecha(r.getString("dfechanacimiento"));

                    this.nIdUsuario = nIdUsuario;
                    this.nCarreras = id1;
                    this.nUltimoGrado = id2;
                    this.nIdCV = id3;
                    this.bEstudianteEgresado = b1;
                    this.sNombre = s1;
                    this.sApellidoPaterno = s2;
                    this.sApellidoMaterno = s3;
                    this.sNumeroCuenta = s4;
                    this.dFechaNacimiento = f1;
                }

                setCarreraYGrado();
            }

            con.close();

        } catch (SQLException ex) {
            System.err.println(ex);
            Logger.getLogger(AlumnoE.class.getName()).log(Level.SEVERE, null, ex);
            throw new appException("No se pudo recuperar el elemento: Alumno");
        } catch (ConexionException ce) {
            System.err.println(ce);
            Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, ce);
            throw new appException("No se pudo recuperar el elemento: Alumno");
        } catch (SQLInjectionException sqlie) {
            System.err.println(sqlie);
            Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, sqlie);
            throw new appException(sqlie.getMessage());
        }

    }

    /**
     * Activamos el alumno para que pueda ver las vacantes.
     *
     * @return
     * @throws appException
     */
    public String activaAlumno() throws appException {

        try {

            Conexion con = new Conexion();
            String query = "select setActivado(" + nIdUsuario + ");";

            con.exec(query);

            con.close();
        } catch (ConexionException ce) {
            System.err.println(ce);
            Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, ce);
            throw new appException("No se pudo activar el elemento: Alumno");
        }

        return "";
    }

    /**
     * Activamos el alumno para que pueda ver las vacantes.
     *
     * @return
     * @throws appException
     */
    public String getCorreoPrimarioAlumno() throws appException {

        try {

            Conexion con = new Conexion();
            String query = "select getAlumnoCorreoPrimario(" + nIdUsuario + ");";

            ResultSet r = con.exec(query);
            r.next();

            String correo = r.getString("getAlumnoCorreoPrimario");

            con.close();

            return correo;

        } catch (SQLException ex) {
            Logger.getLogger(AlumnoE.class.getName()).log(Level.SEVERE, null, ex);
            throw new appException("No se pudo recuperar el correo del elemento: Alumno");
        } catch (ConexionException ce) {
            System.err.println(ce);
            Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, ce);
            throw new appException("No se pudo recuperar el correo del elemento: Alumno");
        }
    }

    /**
     * Genera, pone y regresa la cadena de HTML para el alumno
     *
     * @return
     * @throws appException
     */
    public String generaHTML() throws appException {


        HTMLCVGenerator cv = new HTMLCVGenerator(this);

        String s = cv.generarCV();
        this.htmls = s;
        return s;
    }

    /**
     * Coloca el nombre de la carrera y el nombre del grado del alumno en los
     * campos dados los id's de los constructores.
     */
    private void setCarreraYGrado() throws appException {

        try {

            Conexion con = new Conexion();
            String query2 = "select * from ultimogrado where nultimogrado = " + nUltimoGrado + ";";
            ResultSet r1 = con.exec(query2);

            while (r1.next()) {

                this.setSgrado(r1.getString("sgrado"));
            }

            String query = "select * from carreras where ncarreras = " + nCarreras + ";";
            ResultSet r = con.exec(query);

            while (r.next()) {
                this.setScarrera(r.getString("scarrera"));
            }

            con.close();

        } catch (SQLException ex) {
            System.err.println(ex);
            Logger.getLogger(AlumnoE.class.getName()).log(Level.SEVERE, null, ex);
            throw new appException("No se pudo recuperar el elemento: Alumno");
        } catch (ConexionException ce) {
            System.err.println(ce);
            Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, ce);
            throw new appException("No se pudo recuperar el elemento: Alumno");
        }
    }

    /**
     * @return the nIdUsuario
     */
    public int getnIdUsuario() {
        return nIdUsuario;
    }

    /**
     * @return the nCarreras
     */
    public int getnCarreras() {
        return nCarreras;
    }

    /**
     * @return the nUltimoGrado
     */
    public int getnUltimoGrado() {
        return nUltimoGrado;
    }

    /**
     * @return the bEstudianteEgresado
     */
    public boolean isbEstudianteEgresado() {
        return bEstudianteEgresado;
    }

    /**
     * @return the sNombre
     */
    public String getsNombre() {
        return sNombre;
    }

    /**
     * @return the sApellidoPaterno
     */
    public String getsApellidoPaterno() {
        return sApellidoPaterno;
    }

    /**
     * @return the sApellidoMaterno
     */
    public String getsApellidoMaterno() {
        return sApellidoMaterno;
    }

    /**
     * @return the sNumeroCuenta
     */
    public String getsNumeroCuenta() {
        return sNumeroCuenta;
    }

    /**
     * @return the dFechaNacimiento
     */
    public Fecha getdFechaNacimiento() {
        return dFechaNacimiento;
    }

    /**
     * @return the nIdCV
     */
    public int getnIdCV() {
        return nIdCV;
    }

    /**
     * @param nCarreras the nCarreras to set
     */
    public void setnCarreras(int nCarreras) {
        this.nCarreras = nCarreras;
    }

    /**
     * @param nUltimoGrado the nUltimoGrado to set
     */
    public void setnUltimoGrado(int nUltimoGrado) {
        this.nUltimoGrado = nUltimoGrado;
    }

    /**
     * @param bEstudianteEgresado the bEstudianteEgresado to set
     */
    public void setbEstudianteEgresado(boolean bEstudianteEgresado) {
        this.bEstudianteEgresado = bEstudianteEgresado;
    }

    /**
     * @param sNombre the sNombre to set
     */
    public void setsNombre(String sNombre) {
        this.sNombre = sNombre;
    }

    /**
     * @param sApellidoPaterno the sApellidoPaterno to set
     */
    public void setsApellidoPaterno(String sApellidoPaterno) {
        this.sApellidoPaterno = sApellidoPaterno;
    }

    /**
     * @param sApellidoMaterno the sApellidoMaterno to set
     */
    public void setsApellidoMaterno(String sApellidoMaterno) {
        this.sApellidoMaterno = sApellidoMaterno;
    }

    /**
     * @param sNumeroCuenta the sNumeroCuenta to set
     */
    public void setsNumeroCuenta(String sNumeroCuenta) {
        this.sNumeroCuenta = sNumeroCuenta;
    }

    /**
     * @param dFechaNacimiento the dFechaNacimiento to set
     */
    public void setdFechaNacimiento(Fecha dFechaNacimiento) {
        this.dFechaNacimiento = dFechaNacimiento;
    }

    /**
     * Guarda el objeto en la base de datos independientemente si éste es nuevo
     * o no.
     */
    public void save() throws appException {

        try {

            Conexion con = new Conexion();

            boolean isnuevo = false;
            String nuevo = "select isAlumno(" + nIdUsuario + ");";
            ResultSet rs = con.exec(nuevo);

            while (rs.next()) {
                isnuevo = rs.getBoolean("isalumno");
            }

            System.out.println("is nuevo? : " + isnuevo);

            String query = "select ";
            if (!isnuevo) {
                query += "addAlumno(" + nIdUsuario + "";
                query += ", " + nCarreras;
                query += ", " + nUltimoGrado;
                query += ", " + "null";
                query += ", " + bEstudianteEgresado;
                query += ", '" + sNombre + "'";
                query += ", '" + sApellidoPaterno + "'";
                query += ", '" + sApellidoMaterno + "'";
                query += ", '" + sNumeroCuenta + "'";
                query += ", '" + dFechaNacimiento.toString() + "'";
                query += ");";

                if (!Validator.checkSQLInjection(query)) {
                    con.exec(query);
                }

            } else {

                String cv = (nIdCV == -1) ? "null" : "" + nIdCV;
                query += "updateAlumno(" + nIdUsuario + "";
                query += ", " + nCarreras;
                query += ", " + nUltimoGrado;
                query += ", " + cv;
                query += ", " + bEstudianteEgresado;
                query += ", '" + sNombre + "'";
                query += ", '" + sApellidoPaterno + "'";
                query += ", '" + sApellidoMaterno + "'";
                query += ", '" + sNumeroCuenta + "'";
                query += ", '" + dFechaNacimiento.toString() + "'";
                query += ");";

                if (!Validator.checkSQLInjection(query)) {
                    con.exec(query);
                }
            }

            con.close();
        } catch (ConexionException ce) {
            System.err.println(ce);
            Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, ce);
            throw new appException("No se pudo guardar el elemento: Alumno");
        } catch (SQLException sqle) {
            System.err.println(sqle);
            Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, sqle);
            throw new appException("No se pudo guardar el elemento: Alumno");
        } catch (SQLInjectionException sqlie) {
            System.err.println(sqlie);
            Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, sqlie);
            throw new appException(sqlie.getMessage());
        }

    }

    /**
     * Borra el objeto de la base de datos.
     */
    public void delete() throws appException {
        try {

            Conexion con = new Conexion();
            String query = "select deleteAlumno( " + nIdUsuario + " );";
            con.exec(query);
            con.close();
        } catch (ConexionException ce) {
            System.err.println(ce);
            Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, ce);
            throw new appException("No se pudo borrar el elemento: Alumno");
        }
    }

    /**
     * Método que regresa la lista de TODAS las vacantes dadas por una cadena de
     * búsqueda
     *
     * @throws appException
     */
    public LinkedList<Vacante> getMisVacantes() throws appException {
        try {

            Conexion con = new Conexion();

            LinkedList<Vacante> vacantes = new LinkedList<Vacante>();

            String queryIds = "SELECT nidvacante FROM postulados WHERE nidusuario = " + this.nIdUsuario + ";";

            ResultSet r = con.exec(queryIds);


            while (r.next()) {

                int key = r.getInt("nidvacante");
                Vacante v = new Vacante(key);
                HTMLVacanteGenerator htmlvg = new HTMLVacanteGenerator(v);
                String html = htmlvg.generarVacante();

                v.setHtmlVacante(html);
                vacantes.add(v);

            }

            con.close();
            return vacantes;

        } catch (SQLException ex) {
            System.err.println(ex);
            Logger.getLogger(Busqueda.class.getName()).log(Level.SEVERE, null, ex);
            throw new appException("No se pueden recuperar las vacantes de la base de datos");
        } catch (ConexionException ex) {
            System.err.println(ex);
            Logger.getLogger(Busqueda.class.getName()).log(Level.SEVERE, null, ex);
            throw new appException("No se pueden recuperar las vacantes de la base de datos");
        }

    }

    /**
     * Conexiones de prueba a la base de datos
     *
     * @param args
     * @throws ConexionException
     * @throws SQLException
     * @throws appException z
     */
    public static void main(String args[]) throws ConexionException, SQLException, appException {


        //nuevo
        AlumnoE a = new AlumnoE(2, 1, 1, true, "Nombre Alumno", "Paterno Alumno",
                "Materno Alumno", "NumCuenta", new Fecha(1988, 05, 19), -1);
        a.save();

        // existente
        //Usuario u = new Usuario(2, "nuevo usuario", "washa washa", false, 'a');
        //tc.setsTipocontratacion("a");
        //u.save();



        //AlumnoE a = new AlumnoE(1);
        //u.delete();

        System.out.println(">>>>>>>>>>>>>>>> " + a.getScarrera());
        System.out.println(">>>>>>>>>>>>>>>> " + a.getSgrado());


        System.out.println(a);
    }

    @Override
    public String toString() {
        return "AlumnoE{" + "nIdUsuario=" + nIdUsuario + ", nCarreras=" + nCarreras
                + ", nUltimoGrado=" + nUltimoGrado + ", bEstudianteEgresado="
                + bEstudianteEgresado + ", sNombre=" + sNombre + ", sApellidoPaterno="
                + sApellidoPaterno + ", sApellidoMaterno=" + sApellidoMaterno + ", sNumeroCuenta="
                + sNumeroCuenta + ", dFechaNacimiento=" + dFechaNacimiento + ", nIdCV=" + nIdCV
                + '}';
    }

    /**
     * @return the scarrera
     */
    public String getScarrera() {
        return scarrera;
    }

    /**
     * @param scarrera the scarrera to set
     */
    public void setScarrera(String scarrera) {
        this.scarrera = scarrera;
    }

    /**
     * @return the sgrado
     */
    public String getSgrado() {
        return sgrado;
    }

    /**
     * @param sgrado the sgrado to set
     */
    public void setSgrado(String sgrado) {
        this.sgrado = sgrado;
    }

    /**
     * @return the htmls
     */
    public String getHtmls() {
        return htmls;

    }

    /**
     * @param htmls the htmls to set
     */
    public void setHtmls(String htmls) {
        this.htmls = htmls;
    }
}
